Test Setup Failed
Push — master ( c73065...3e6d69 )
by Aristeides
02:06
created

wp.customize.Control.extend.kirkiValidateCSSValue   D

Complexity

Conditions 9
Paths 4

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
nc 4
nop 1
dl 0
loc 27
rs 4.909
c 0
b 0
f 0
1
/* global kirki */
2
/**
3
 * The majority of the code in this file
4
 * is derived from the wp-customize-posts plugin
5
 * and the work of @westonruter to whom I am very grateful.
6
 *
7
 * @see https://github.com/xwp/wp-customize-posts
8
 */
9
10
( function() {
11
	'use strict';
12
13
	/**
14
	 * A dynamic color-alpha control.
15
	 *
16
	 * @class
17
	 * @augments wp.customize.Control
18
	 * @augments wp.customize.Class
19
	 */
20
	wp.customize.kirkiDynamicControl = wp.customize.Control.extend({
21
22
		initialize: function( id, options ) {
23
			var control = this,
24
			    args    = options || {};
25
26
			args.params = args.params || {};
27
			if ( ! args.params.type ) {
28
				args.params.type = 'kirki-generic';
29
			}
30
			if ( ! args.params.content ) {
31
				args.params.content = jQuery( '<li></li>' );
32
				args.params.content.attr( 'id', 'customize-control-' + id.replace( /]/g, '' ).replace( /\[/g, '-' ) );
33
				args.params.content.attr( 'class', 'customize-control customize-control-' + args.params.type );
34
			}
35
36
			control.propertyElements = [];
37
			wp.customize.Control.prototype.initialize.call( control, id, args );
38
		},
39
40
		/**
41
		 * Add bidirectional data binding links between inputs and the setting(s).
42
		 *
43
		 * This is copied from wp.customize.Control.prototype.initialize(). It
44
		 * should be changed in Core to be applied once the control is embedded.
45
		 *
46
		 * @private
47
		 * @returns {null}
48
		 */
49
		_setUpSettingRootLinks: function() {
50
			var control = this,
51
			    nodes   = control.container.find( '[data-customize-setting-link]' );
52
53
			nodes.each( function() {
54
				var node = jQuery( this );
55
56
				wp.customize( node.data( 'customizeSettingLink' ), function( setting ) {
57
					var element = new wp.customize.Element( node );
58
					control.elements.push( element );
59
					element.sync( setting );
60
					element.set( setting() );
61
				});
62
			});
63
		},
64
65
		/**
66
		 * Add bidirectional data binding links between inputs and the setting properties.
67
		 *
68
		 * @private
69
		 * @returns {null}
70
		 */
71
		_setUpSettingPropertyLinks: function() {
72
			var control = this,
73
			    nodes;
74
75
			if ( ! control.setting ) {
76
				return;
77
			}
78
79
			nodes = control.container.find( '[data-customize-setting-property-link]' );
80
81
			nodes.each( function() {
82
				var node = jQuery( this ),
83
				    element,
84
				    propertyName = node.data( 'customizeSettingPropertyLink' );
85
86
				element = new wp.customize.Element( node );
87
				control.propertyElements.push( element );
88
				element.set( control.setting()[ propertyName ] );
89
90
				element.bind( function( newPropertyValue ) {
91
					var newSetting = control.setting();
92
					if ( newPropertyValue === newSetting[ propertyName ] ) {
93
						return;
94
					}
95
					newSetting = _.clone( newSetting );
96
					newSetting[ propertyName ] = newPropertyValue;
97
					control.setting.set( newSetting );
98
				} );
99
				control.setting.bind( function( newValue ) {
100
					if ( newValue[ propertyName ] !== element.get() ) {
101
						element.set( newValue[ propertyName ] );
102
					}
103
				} );
104
			});
105
		},
106
107
		/**
108
		 * @inheritdoc
109
		 */
110
		ready: function() {
111
			var control = this;
112
113
			control._setUpSettingRootLinks();
114
			control._setUpSettingPropertyLinks();
115
116
			wp.customize.Control.prototype.ready.call( control );
117
118
			control.deferred.embedded.done( function() {
119
				control.initKirkiControl( control );
120
			});
121
		},
122
123
		/**
124
		 * Embed the control in the document.
125
		 *
126
		 * Override the embed() method to do nothing,
127
		 * so that the control isn't embedded on load,
128
		 * unless the containing section is already expanded.
129
		 *
130
		 * @returns {null}
131
		 */
132
		embed: function() {
133
			var control   = this,
134
			    sectionId = control.section();
135
136
			if ( ! sectionId ) {
137
				return;
138
			}
139
140
			wp.customize.section( sectionId, function( section ) {
141
				if ( 'kirki-expanded' === section.params.type || section.expanded() || wp.customize.settings.autofocus.control === control.id ) {
142
					control.actuallyEmbed();
143
				} else {
144
					section.expanded.bind( function( expanded ) {
145
						if ( expanded ) {
146
							control.actuallyEmbed();
147
						}
148
					} );
149
				}
150
			} );
151
		},
152
153
		/**
154
		 * Deferred embedding of control when actually
155
		 *
156
		 * This function is called in Section.onChangeExpanded() so the control
157
		 * will only get embedded when the Section is first expanded.
158
		 *
159
		 * @returns {null}
160
		 */
161
		actuallyEmbed: function() {
162
			var control = this;
163
			if ( 'resolved' === control.deferred.embedded.state() ) {
164
				return;
165
			}
166
			control.renderContent();
167
			control.deferred.embedded.resolve(); // This triggers control.ready().
168
		},
169
170
		/**
171
		 * This is not working with autofocus.
172
		 *
173
		 * @param {object} [args] Args.
174
		 * @returns {null}
175
		 */
176
		focus: function( args ) {
177
			var control = this;
178
			control.actuallyEmbed();
179
			wp.customize.Control.prototype.focus.call( control, args );
180
		},
181
182
		/**
183
		 * Additional actions that run on ready.
184
		 *
185
		 * @param {object} [args] Args.
186
		 * @returns {null}
187
		 */
188
		initKirkiControl: function( control ) {
189
			if ( 'undefined' !== typeof kirki.control[ control.params.type ] ) {
190
				kirki.control[ control.params.type ].init( control );
191
				return;
192
			}
193
194
			// Save the value
195
			this.container.on( 'change keyup paste click', 'input', function() {
196
				control.setting.set( jQuery( this ).val() );
197
			});
198
		},
199
200
		kirkiValidateCSSValue: function( value ) {
201
202
			var validUnits = ['rem', 'em', 'ex', '%', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ch', 'vh', 'vw', 'vmin', 'vmax'],
203
				numericValue,
204
				unit;
205
206
			// 0 is always a valid value, and we can't check calc() values effectively.
207
			if ( '0' === value || ( 0 <= value.indexOf( 'calc(' ) && 0 <= value.indexOf( ')' ) ) ) {
208
				return true;
209
			}
210
211
			if ( 'auto' === value || 'inherit' === value || 'initial' === value ) {
212
				return true;
213
			}
214
215
			// Get the numeric value.
216
			numericValue = parseFloat( value );
217
218
			// Get the unit
219
			unit = value.replace( numericValue, '' );
220
221
			// Check the validity of the numeric value and units.
222
			if ( isNaN( numericValue ) || -1 === jQuery.inArray( unit, validUnits ) ) {
223
				return false;
224
			}
225
			return true;
226
		}
227
	});
228
})();
229
230
_.each( kirki.control, function( obj, type ) {
231
	wp.customize.controlConstructor[ type ] = wp.customize.kirkiDynamicControl.extend({});
232
} );
233